#include <iostream>
#include <Python.h>

int main(int argc, char *argv[])
{
    Py_Initialize();
    if (!Py_IsInitialized())
        return -1;

    int count = 100;
    while (count --)
    {
        std::cout << "----------" << count << "-----------" << std::endl;
        PyObject *pModule = PyImport_ImportModule("preprocess");
        if (!pModule)
        {
            std::cout << "not found .py file" << std::endl;
            return -1;
        }
        std::cout << "----------" << count << "-----------" << std::endl;


        /*get python func*/
        PyObject *pFunc = PyObject_GetAttrString(pModule, "test_print");
        /*init function parameter*/

        PyObject *pList = PyList_New(560);
        for (int i = 0; i < 560; i ++)
        {
            PyObject *tmp = Py_BuildValue("[i,i]", i, i+1);
            /**
             *  warning:构造二维数组的方法有PyList_Append 和 PyList_SetItem两种
             *  Append方法会导致内存泄漏，因此必须使用SetItem方法!!!!
            */
            PyList_SetItem(pList, i, tmp);
            /**
             * warning : 使用PyList_SetItem函数时，PList销毁并不会导致tmp销毁
             * 此时tmp的计数会加1，因此必须调用宏Py_DECREF减少tmp计数
            */
            Py_DECREF(tmp);
        }

        /*set args with parameter*/
        PyObject *pArgs = PyTuple_New(1);
        PyTuple_SetItem(pArgs, 0, pList);

        /*call the python func*/
        PyObject *pRet = PyEval_CallObject(pFunc, pArgs);
        if (pFunc)
            Py_DECREF(pFunc);
        if (pArgs)
            Py_DECREF(pArgs);

        if (pRet == NULL)
        {
            std::cout << "error" << std::endl;
        }
        /*get ret of the python func*/
        std::cout << "size of ret : " << PyObject_Size(pRet) << std::endl;
        /*
        for (int i = 0; i < PyObject_Size(pRet); i++)
        {
            PyObject *row = PyList_GetItem(pRet, i);
            for (int j = 0; j < PyObject_Size(row); j++)
            {
                PyObject *item = PyList_GetItem(row, j);
                std::cout << PyLong_AsSize_t(item) << " ";
                Py_XDECREF(item);
            }
            Py_XDECREF(row);
            std::cout << std::endl;
        }*/


        /*test bengin

        for (int i = 0; i < PyObject_Size(pList); i++)
        {
            PyObject *row = PyList_GetItem(pList, i);
            for (int j = 0; j < PyObject_Size(row); j++)
            {
                PyObject *item = PyList_GetItem(row, j);
                std::cout << PyLong_AsSize_t(item) << " ";
            }
            std::cout << std::endl;
        }*/
        /*free memory !!!!!!!!*/
       /* Py_XDECREF(pList);
        Py_XDECREF(pFunc);
        Py_XDECREF(pArgs);
        Py_XDECREF(pList);
        Py_XDECREF(pRet);
        */

        if (pList)
            Py_CLEAR(pList);
        if (pModule)
            Py_CLEAR(pModule);
        if (pFunc)
            Py_CLEAR(pFunc);

        for (int i = 0;i < 1000; i ++);
    }

    Py_Finalize();
    return 0;
}
